package com.gin.supermarket_inventory_system.commodity.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gin.common.constant.ApiPath;
import com.gin.common.utils.TreeNode;
import com.gin.database.validation.EntityId;
import com.gin.security.Constant.Security;
import com.gin.spring.annotation.MyRestController;
import com.gin.spring.exception.BusinessException;
import com.gin.spring.vo.response.Res;
import com.gin.supermarket_inventory_system.commodity.docket.CommodityDocket;
import com.gin.supermarket_inventory_system.commodity.dto.form.CommodityTypeAddForm;
import com.gin.supermarket_inventory_system.commodity.dto.form.CommodityTypeUpdateForm;
import com.gin.supermarket_inventory_system.commodity.dto.vo.CommodityTypeVo;
import com.gin.supermarket_inventory_system.commodity.entity.CommodityPo;
import com.gin.supermarket_inventory_system.commodity.service.CommodityService;
import com.gin.supermarket_inventory_system.commodity.service.CommodityTypeService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.List;
import java.util.Objects;

/**
 *
 * @since : 2023/9/26 16:37
 * @author : ginstone
 * @version : v1.0.0
 **/
@Slf4j
@MyRestController(CommodityTypeController.API_PREFIX)
@Tag(name = CommodityTypeController.GROUP_NAME)
@RequiredArgsConstructor
public class CommodityTypeController {
    /**
     *  接口路径前缀
     */
    public static final String API_PREFIX = CommodityDocket.API_PREFIX + "/type";
    /**
     *  接口文档分组名称
     */
    public static final String GROUP_NAME = "商品类型管理";
    /**
     * 本接口使用的主Service类
     */
    private final CommodityTypeService service;
    private final CommodityService commodityService;


    @PostMapping(ApiPath.ADD)
    @Operation(summary = "添加")
    @PreAuthorize(Security.PRE_AUTHORITY_URI_OR_ADMIN)
    public Res<Void> postAdd(@RequestBody @Validated CommodityTypeAddForm form,
                             @SuppressWarnings("unused") HttpServletRequest request) {
        service.saveBatch(form.toPoList());
        return Res.success("操作成功, 请刷新界面");
    }

    @PostMapping(ApiPath.DEL)
    @Operation(summary = "删除")
    @PreAuthorize(Security.PRE_AUTHORITY_URI_OR_ADMIN)
    public Res<Void> postDel(
            @RequestParam @EntityId(service = CommodityTypeService.class) long id,
            @SuppressWarnings("unused") HttpServletRequest request
    ) {
        // 检查是否有子类型
        {
            final long count = service.list().stream().filter(i -> Objects.equals(id, i.getParentId())).count();
            if (count > 0) {
                throw BusinessException.of(HttpStatus.FORBIDDEN, String.format("禁止删除: 该类型下有 %d 个子类型", count));
            }
        }

        // 检查是否被商品信息使用
        {
            final QueryWrapper<CommodityPo> qw = new QueryWrapper<>();
            qw.eq("type_id", id);
            final long count = commodityService.count(qw);
            if (count > 0) {
                throw BusinessException.of(HttpStatus.FORBIDDEN, String.format("禁止删除: 商品类型被 %d 个商品信息使用", count));
            }
        }


        service.removeById(id);
        return Res.success("删除成功");
    }


    @PostMapping(ApiPath.UPDATE)
    @Operation(summary = "修改")
    @PreAuthorize(Security.PRE_AUTHORITY_URI_OR_ADMIN)
    public Res<Void> postUpdate(@RequestBody @Validated CommodityTypeUpdateForm form,
                                @SuppressWarnings("unused") HttpServletRequest request) {
        service.updateById(form.toPo());
        return Res.success("操作成功, 请刷新界面");
    }

    @GetMapping(ApiPath.LIST_ALL)
    @Operation(summary = "查询所有(树形结构)")
    public Res<List<CommodityTypeVo>> getListAll() {
        final List<CommodityTypeVo> list = CommodityTypeVo.toVoList(service.list());
        return Res.of(TreeNode.collate(list));
    }

}